
/*
 * @Author: ljkt
 * @Version: 2.0
 * @Date: 2021-12-01 14:27:01
 * @LastEditors: ljkt
 * @LastEditTime: 2025-01-28 13:32:52
 * @Description:
 */

#include "./Common_Include.h"
Ram s_dev_h_bridge gDev_HBrideg;
void Dev_HBridge_Init(void)
{
    memset(&gDev_HBrideg, 0, sizeof(s_dev_h_bridge));
}
void Set_HBright_Forward(pwm)
{
    Drv_IoO_Set(e_INDEX_IOO_BACKWARD_EN, H_BRIDGE_OFF);
    Drv_Pwm_Set_Duty(e_INDEX_PWM_BACKWARD, 0);
    Drv_IoO_Set(e_INDEX_IOO_FORWARD_EN, H_BRIDGE_ON);
    Drv_Pwm_Set_Duty(e_INDEX_PWM_FORWARD, pwm);
}
void Set_HBright_Backward(pwm)
{
    Drv_IoO_Set(e_INDEX_IOO_FORWARD_EN, H_BRIDGE_OFF);
    Drv_Pwm_Set_Duty(e_INDEX_PWM_FORWARD, 0);
    Drv_IoO_Set(e_INDEX_IOO_BACKWARD_EN, H_BRIDGE_ON);
    Drv_Pwm_Set_Duty(e_INDEX_PWM_BACKWARD, pwm);
}
void Set_HBright_Stop(void)
{
    Drv_IoO_Set(e_INDEX_IOO_FORWARD_EN, H_BRIDGE_OFF);
    Drv_Pwm_Set_Duty(e_INDEX_PWM_FORWARD, 0);
    Drv_IoO_Set(e_INDEX_IOO_BACKWARD_EN, H_BRIDGE_OFF);
    Drv_Pwm_Set_Duty(e_INDEX_PWM_BACKWARD, 0);
}
unsigned char CurrentPwmDuty(signed char set_duty)
{
    static unsigned char index = 0, tick = 0;
    CONST unsigned char pwmduty_tab[] = {
        0ul, 10ul, 10ul, 10ul, 10ul, 10ul, 10ul, 10ul, 10ul, 10ul,  // 0~9
        10ul, 11ul, 12ul, 13ul, 14ul, 15ul, 16ul, 17ul, 18ul, 19ul, // 10~19
        20ul, 21ul, 22ul, 23ul, 24ul, 25ul, 26ul, 27ul, 28ul, 29ul, // 20~29
        30ul, 31ul, 32ul, 33ul, 34ul, 35ul, 36ul, 37ul, 38ul, 39ul, // 30~39
        40ul, 41ul, 42ul, 43ul, 44ul, 45ul, 46ul, 47ul, 48ul, 49ul, // 40~49
        50ul, 51ul, 52ul, 53ul, 54ul, 55ul, 56ul, 57ul, 58ul, 59ul, // 50~59
        60ul, 61ul, 62ul, 63ul, 64ul, 65ul, 66ul, 67ul, 68ul, 69ul, // 60~69
        70ul, 71ul, 72ul, 73ul, 74ul, 75ul, 76ul, 77ul, 78ul, 79ul, // 70~79
        80ul, 81ul, 82ul, 83ul, 84ul, 85ul, 86ul, 87ul, 88ul, 89ul, // 80~89
        90ul, 90ul, 90ul, 90ul, 90ul, 90ul, 90ul, 90ul, 90ul, 90ul, // 90~99
        100ul};                                                     // 100
    if (Drv_Autoload_Ntick_u8(&tick, 1ul))
    {
        if (index > set_duty)
        {
            index--;
            // Dev_IoPrint_Str_DecStr("current duty", pwmduty_tab[index]);
        }
        else if (index < set_duty)
        {
            index++;
            // Dev_IoPrint_Str_DecStr("current duty", pwmduty_tab[index]);
        }
    }

    return pwmduty_tab[index];
}
void Dev_HBridge_Deal(void)
{
    enum
    {
        e_INDEX_MOTOR_STOP,               // 软停止
        e_INDEX_MOTOR_DELAY,              // 延时
        e_INDEX_MOTOR_FORWARD_RUN,        // 正运行
        e_INDEX_MOTOR_FORWARD_SOFT_STOP,  // 正软停止
        e_INDEX_MOTOR_BACKWARD_RUN,       // 反运行
        e_INDEX_MOTOR_BACKWARD_SOFT_STOP, // 反软停止
        e_INDEX_MOTOR_MAX,
    };
    static unsigned char step = 0;
    static unsigned short tick_delay = 0;
    switch (step)
    {
    case e_INDEX_MOTOR_STOP:
        Set_HBright_Stop();
        gDev_HBrideg.Current_PwmDuty = 0;
        if (gDev_HBrideg.SetDuty) // 要等电机完全停止，在启动
        {

            tick_delay = Drv_Get_Tick_u16();
            step = e_INDEX_MOTOR_DELAY;
        }
        break;
    case e_INDEX_MOTOR_DELAY:
        Set_HBright_Stop();
        gDev_HBrideg.Current_PwmDuty = 0;
        if (Drv_Autoload_Ntick_u16(&tick_delay, 100ul))
        {
            ((gDev_HBrideg.Dir == MOTOR_FORWARD) ? (step = e_INDEX_MOTOR_FORWARD_RUN) : (step = e_INDEX_MOTOR_BACKWARD_RUN));
        }
        break;
    case e_INDEX_MOTOR_FORWARD_RUN:
        gDev_HBrideg.Current_PwmDuty = CurrentPwmDuty(gDev_HBrideg.SetDuty);
        Set_HBright_Forward(gDev_HBrideg.Current_PwmDuty);
        if ((gDev_HBrideg.SetDuty == 0) || (gDev_HBrideg.Dir != MOTOR_FORWARD)) // 方向超前并且目标速度仍然存在
        {
            step = e_INDEX_MOTOR_FORWARD_SOFT_STOP;
        }
        break;
    case e_INDEX_MOTOR_FORWARD_SOFT_STOP:
        gDev_HBrideg.Current_PwmDuty = CurrentPwmDuty(0);
        Set_HBright_Forward(gDev_HBrideg.Current_PwmDuty);
        if (gDev_HBrideg.Current_PwmDuty == 0)
        {
            step = e_INDEX_MOTOR_STOP;
        }
        break;
    case e_INDEX_MOTOR_BACKWARD_RUN:
        gDev_HBrideg.Current_PwmDuty = CurrentPwmDuty(gDev_HBrideg.SetDuty);
        Set_HBright_Backward(gDev_HBrideg.Current_PwmDuty);
        if ((gDev_HBrideg.SetDuty == 0) || (gDev_HBrideg.Dir != MOTOR_BACKWARD)) // 方向超后并且目标速度仍然存在
        {
            step = e_INDEX_MOTOR_BACKWARD_SOFT_STOP;
        }
        break;
    case e_INDEX_MOTOR_BACKWARD_SOFT_STOP:
        gDev_HBrideg.Current_PwmDuty = CurrentPwmDuty(0);
        Set_HBright_Backward(gDev_HBrideg.Current_PwmDuty);
        if (gDev_HBrideg.Current_PwmDuty == 0)
        {
            step = e_INDEX_MOTOR_STOP;
        }
        break;
    default:
        break;
    }
}
void Dev_HBridge_Write_Current_mA(signed short ma)
{
    signed long avg_mA = 0;
    gDev_HBrideg.Pulse_mA = ma;
    gDev_HBrideg.Avg_mA = ((signed long)(ma)) * ((signed long)(gDev_HBrideg.Current_PwmDuty)) / 100ul; // 平均电流-按占空比设置
}
void Dev_HBridge_EVN(void)
{
    typedef struct
    {
        s_index_and_name_t infor;
        unsigned short mA_Min; // 当前档位电流的下限
        unsigned short mA_Max; // 当前档位的电流上线
    } s_evn_position_motor_t;
#define HUICHA_MA 200ul
    CONST s_evn_position_motor_t evn_position_motor_tab[] = {
        {INDEX_AND_STR_NAME(e_INDEX_ENV_POSITION_OUT_WATER), 0ul, 1000ul + HUICHA_MA},
        {INDEX_AND_STR_NAME(e_INDEX_ENV_POSITION_IN_WATER), 1000ul - HUICHA_MA, 7000ul + HUICHA_MA},
        {INDEX_AND_STR_NAME(e_INDEX_ENV_POSITION_OVER_LOAD), 7000ul - HUICHA_MA, 0xffff},
    };
    unsigned char i;
    static unsigned short tick3s, tick5s, tick24s;
    // ===================================加入回差，获取电流档位位置
    for (i = 0; i < ARR_CNT(evn_position_motor_tab); i++)
    {
        if (gDev_HBrideg.Evn_Position == evn_position_motor_tab[i].infor.Index)
        {
            if (gDev_HBrideg.Pulse_mA < evn_position_motor_tab[i].mA_Min)
            {
                LIMIT_SUB_STEP(gDev_HBrideg.Evn_Position, 0, 1ul);
                Dev_IoPrint_Str_DecStr(evn_position_motor_tab[gDev_HBrideg.Evn_Position].infor.Name, __LINE__);
            }
            else if (gDev_HBrideg.Pulse_mA > evn_position_motor_tab[i].mA_Max)
            {
                LIMIT_ADD_STEP(gDev_HBrideg.Evn_Position, (ARR_CNT(evn_position_motor_tab) - 1ul), 1ul);
                Dev_IoPrint_Str_DecStr(evn_position_motor_tab[gDev_HBrideg.Evn_Position].infor.Name, __LINE__);
            }
        }
    }
    // =================================环境时间
    if (gDev_HBrideg.SetDuty == 0)
    {
        gDev_HBrideg.EVN_TIME = 0;
        tick3s = Drv_Get_Tick_u16();
        tick5s = Drv_Get_Tick_u16();
        tick24s = Drv_Get_Tick_u16();
        return;
    }
    if (gDev_HBrideg.Evn_Position_Last != gDev_HBrideg.Evn_Position)
    {
        tick3s = Drv_Get_Tick_u16();
        tick5s = Drv_Get_Tick_u16();
        tick24s = Drv_Get_Tick_u16();
        gDev_HBrideg.Evn_Position_Last = gDev_HBrideg.Evn_Position;
    }
    if (gDev_HBrideg.Evn_Position == e_INDEX_ENV_POSITION_OUT_WATER)
    {
        if (Drv_Autoload_Ntick_u16(&tick5s, 5000ul))
        {
            gDev_HBrideg.EVN_TIME = EVN_OUT_WATER_5S;
            // Dev_IoPrint_Str_DecStr("EVN_OUT_WATER_5S:", __LINE__);
        }
    }
    if (gDev_HBrideg.Evn_Position == e_INDEX_ENV_POSITION_IN_WATER)
    {
        if (Drv_Autoload_Ntick_u16(&tick3s, 3000ul))
        {
            gDev_HBrideg.EVN_TIME = EVN_IN_WATER_3S;
            // Dev_IoPrint_Str_DecStr("EVN_IN_WATER_3S:", __LINE__);
        }
    }
    if (gDev_HBrideg.Evn_Position == e_INDEX_ENV_POSITION_OVER_LOAD)
    {
        if (Drv_Autoload_Ntick_u16(&tick3s, 3000ul))
        {
            gDev_HBrideg.EVN_TIME = EVN_OVER_LOAD_3S;
            // Dev_IoPrint_Str_DecStr("EVN_OVER_LOAD_3S:", __LINE__);
        }
    }
}
void Dev_HBridge_Scan(void)
{
    static unsigned char tick = 0;
    if (Drv_Autoload_Ntick_u8(&tick, DEV_HBRIDGE_TASK_TIME))
    {
        Dev_HBridge_EVN();
        Dev_HBridge_Deal();
    }
}